﻿using DGZImp.Core.Utilities;
using DGZImp.MdsProject.Base;
using DGZImp.MdsProject.Devices.Base;
using DGZImp.MdsProject.Devices.Helper;
using DGZImp.MdsProject.Devices.Models;
using DGZImp.MdsProject.Helper;
using DGZImp.MdsProject.Services;
using Microsoft.Extensions.DependencyInjection;
using Nomad.Iot;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DGZImp.MdsProject.Devices
{
    /// <summary>
    /// RGV
    /// </summary>
    public class Rgv : PlcDevice<RgvData>
    {
        public Rgv(string id, string name, IIotServe serve, List<PlcDataMapItem> maps) : base(id, name, serve, maps)
        {
            OnDataChange += RgvOnDataChange;
        }

        public async void RgvOnDataChange(object sender)
        {
            if (Data.EventCode == RgvEventEnum.已完成 && Data.TaskNo != 0)
            {
                var service = ServiceProviderAccessor.ServiceProvider.GetService<Mds_LogisticTaskService>();
                await service.FinishLogisticDetailTask(null, Data.TaskNo);
                await ClearTaskAsync();
            }
        }

        public async Task<OperateResult> SendNormalTaskAsync(RgvCommandEmun command, int taskNo, int start = 0, int end = 0)
        {
            if (command == RgvCommandEmun.无指令)
                return new OperateResult { IsSuccess = false, Message = "未发送正确指令" };

            if (command != RgvCommandEmun.清除任务 && Data.Status != RgvStatusEmun.空闲)
                return new OperateResult { IsSuccess = false, Message = $"{Name}不是空闲状态" };

            //if (command == RgvCommandEmun.清除任务 && Data.Status != RgvStatusEmun.空闲 && Data.Status != RgvStatusEmun.运行中)
            //    return new OperateResult { IsSuccess = false, Message = $"{Name}不是联机状态" };

            if (command != RgvCommandEmun.清除任务 && Data.WorkingLock != 0)
                return new OperateResult { IsSuccess = false, Message = $"{Name}处于对接锁定状态" };

            //压机RGV的特殊逻辑  如果取放货任务起点是99 则只发送一个放货任务
            if (start == 99 && end != 0)
            {
                // return await SendNormalTaskAsync(RgvCommandEmun.放货任务, taskNo, 0, end);
                command = RgvCommandEmun.放货任务;
                start = 0;
            }

            return await WriteDataToPlc(new List<PlcDataWriteItem> {
                new(){ PropName = nameof(RgvData.WriteStart), Value = start },
                new(){ PropName = nameof(RgvData.WriteEnd), Value = end },
                new(){ PropName = nameof(RgvData.WriteTaskNo), Value = taskNo },
                new(){ PropName = nameof(RgvData.WorkingLock), Value = 0 },
                new(){ PropName = nameof(RgvData.Command), Value = command }
            });
        }

        [MdsAction("取放货任务", "发送一个RGV取放货任务")]
        public async Task<OperateResult> SendTaskAsync([MdsParameter("取货点")] int start, [MdsParameter("放货点")] int end)
        {
            var taskNo = SimpleSnowId.GenerateId();
            return await SendNormalTaskAsync(RgvCommandEmun.取放货任务, taskNo, start, end);
        }

        [MdsAction("取货任务", "发送一个RGV取货任务")]
        public async Task<OperateResult> SendGetTaskAsync([MdsParameter("取货点")] int start)
        {
            var taskNo = SimpleSnowId.GenerateId();
            return await SendNormalTaskAsync(RgvCommandEmun.取货任务, taskNo, start, 0);
        }

        [MdsAction("放货任务", "发送一个RGV放货任务")]
        public async Task<OperateResult> SendPutTaskAsync([MdsParameter("放货点")] int end)
        {
            var taskNo = SimpleSnowId.GenerateId();
            return await SendNormalTaskAsync(RgvCommandEmun.放货任务, taskNo, 0, end);
        }

        [MdsAction("移动任务", "发送一个RGV移动任务")]
        public async Task<OperateResult> SendMoveTaskAsync([MdsParameter("目标点")] int start)
        {
            var taskNo = SimpleSnowId.GenerateId();
            return await SendNormalTaskAsync(RgvCommandEmun.移动任务, taskNo, start, 0);
        }

        [MdsAction("设备对接锁定", "发送一个设备对接信号，让RGV短暂锁定")]
        public async Task<OperateResult> SendWorkingLockAsync()
        {
            if (Data.Status != RgvStatusEmun.空闲)
                return new OperateResult { IsSuccess = false, Message = $"{Name}非空闲，不应下发锁定信号" };
            return await WriteDataToPlc(new List<PlcDataWriteItem> {
                new(){ PropName = nameof(RgvData.WorkingLock), Value = 1 }
            });
        }

        [MdsAction("设备对接解锁", "发送一个设备对接完成信号，让RGV解除锁定")]
        public async Task<OperateResult> SendWorkingUnlockAsync()
        {
            if (Data.Status != RgvStatusEmun.空闲)
                return new OperateResult { IsSuccess = false, Message = $"{Name}非空闲，不应下发解锁信号" };
            return await WriteDataToPlc(new List<PlcDataWriteItem> {
                new(){ PropName = nameof(RgvData.WorkingLock), Value = 0 }
            });
        }

        [MdsAction("清除任务", "清除RGV任务")]
        public async Task<OperateResult> ClearTaskAsync()
        {
            return await SendNormalTaskAsync(RgvCommandEmun.清除任务, 0, 0, 0);
        }

    }

    public class RgvData
    {
        [Description("01.心跳")]
        public int Heartbeat { get; set; }

        [Description("02.状态")]
        public RgvStatusEmun Status { get; set; }

        [Description("03.事件")]
        public RgvEventEnum EventCode { get; set; }

        [Description("04.激光测距")]
        public int Distance { get; set; }

        [Description("05.当前位置")]
        public int CurPos { get; set; }

        [Description("06.当前任务号")]
        public int TaskNo { get; set; }

        [Description("07.任务起点")]
        public int Start { get; set; }

        [Description("08.任务终点")]
        public int End { get; set; }

        [Description("09.错误码")]
        public RgvErrorEnum Error { get; set; }

        [Description("10.有货无货")]
        public GoodsStatusEnum IsFull { get; set; }

        [Description("80.写入指令")]
        public RgvCommandEmun Command { get; set; }

        [Description("81.写入任务号")]
        public int WriteTaskNo { get; set; }

        [Description("82.写入起点")]
        public int WriteStart { get; set; }

        [Description("83.写入终点")]
        public int WriteEnd { get; set; }

        /// <summary>
        /// 1.锁定 2.解锁
        /// </summary>
        [Description("84.设备对接锁定")]
        public YXRgvConnectEnum WorkingLock { get; set; }

        [Description("99.刷新时间")]
        public string RefreshTime { get; set; }
    }
}
